package org.wak.utils
{
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;

	/**
	 * This is for replace the use of the built in flash SimpleButton
	 * it has some bugs with the custom cursor and mouse over. 
	 * The cons of this is that it needs to be updated on Mouse move event
	 * to update the button state with a Hit Test.
	 * 
	 */	
	public class WakSimpleButton extends Sprite
	{
		protected var mUp:DisplayObject = null;
		protected var mOver:DisplayObject = null;
		protected var mDown:DisplayObject = null;
		
		protected var mButtonName:String = "" ;
		
		protected var mSelected:Boolean = false ;
		
		protected var mEnabled:Boolean = true ;
		
		/**
		 * Constructor. 
		 * @param pUp The initial value for the WakSimpleButton up state. 
		 * @param pOver The initial value for the WakSimpleButton over state. 
		 * @param pDown The initial value for the WakSimpleButton down state. 
		 * @param pActionName an optional button name to use as an id depending on the context.
		 * 
		 */		
		public function WakSimpleButton(pUp:DisplayObject, pOver:DisplayObject, pDown:DisplayObject, pActionName:String = "")
		{
			super();
			mUp = pUp ;
			mOver = pOver ;
			mDown = pDown ;
			
			this.addChild( mUp );
			
			if(mDown != null)
				this.addChild(mDown);
				
			mDown.visible = false ;
			mButtonName = pActionName ;
			
			this.addEventListener(Event.ADDED_TO_STAGE, OnAddedToStage );
			
		}
		
		public function get buttonName():String
		{
			return mButtonName ;
		}
		
		/**
		 * Updates the button state using a  hitTestPoint over
		 * pStageX and pStageY.
		 * @param pStageX mouse horizontal coordinate on the stage
		 * @param pStageY mouse vertical coordinate on the stage
		 * 
		 */		
		public function Update( pStageX:Number, pStageY:Number):void
		{
			if( mSelected || !mEnabled)
				return ;
			
			if( this.hitTestPoint(pStageX,pStageY,true) )
			{
				if( this.contains( mUp ) )
					this.removeChild(mUp);
				
				this.addChild(mOver);
				this.setChildIndex(mDown, this.numChildren -1);
			}
			else
			{
				if( this.contains( mOver ) )
					this.removeChild(mOver);
				
				this.addChild(mUp);
			}
		}
		
		/**
		 * Toggle the button in a selected state. When that happens the DisplayObject
		 * assigned for the over state is set, and Update calls are ignored. 
		 * @param value state true or false.
		 * 
		 */		
		public function set selected(value:Boolean):void
		{
			mSelected = value ;
			
			if(mSelected)
			{
				if( this.contains( mUp ) )
					this.removeChild(mUp);
				
				this.addChild(mOver);
			}
			else
			{
				if( this.contains( mOver ) )
					this.removeChild(mOver);
				
				this.addChild(mUp);
			}
		}
		
		public function get selected():Boolean
		{
			return mSelected ;
		}
		
		public function set enabled(value:Boolean):void
		{
			mEnabled = value ;
			
			if(mEnabled)
			{
				this.alpha = 1 ;
			}
			else
			{
				this.alpha = 0.50 ;
			}
		}
		
		public function get enabled():Boolean
		{
			return mEnabled ;
		}
		
		protected function OnAddedToStage(event:Event):void
		{
			this.removeEventListener(Event.ADDED_TO_STAGE, OnAddedToStage );
			
			this.addEventListener(MouseEvent.MOUSE_DOWN, OnMouseDown);
			this.addEventListener(MouseEvent.MOUSE_UP, OnMouseUp);
			this.addEventListener(MouseEvent.CLICK, OnMouseUp);
			
			this.addEventListener(MouseEvent.MOUSE_OVER, OnMouseOver);
			this.addEventListener(MouseEvent.MOUSE_OUT, OnMouseOut);
			
			this.addEventListener(Event.REMOVED_FROM_STAGE, OnRemovedFromStage);
		}
		
		protected function OnRemovedFromStage(event:Event):void
		{
			this.removeEventListener(Event.REMOVED_FROM_STAGE, OnRemovedFromStage )
			
			this.removeEventListener(MouseEvent.MOUSE_DOWN, OnMouseDown);
			this.removeEventListener(MouseEvent.MOUSE_UP, OnMouseUp);
			this.removeEventListener(MouseEvent.CLICK, OnMouseUp);
			
			this.removeEventListener(MouseEvent.MOUSE_OVER, OnMouseOver);
			this.removeEventListener(MouseEvent.MOUSE_OUT, OnMouseOut);
			
			this.addEventListener(Event.ADDED_TO_STAGE, OnAddedToStage );
			
		}
		
		protected function OnMouseDown(event:MouseEvent):void
		{
			if(mDown != null)
				mDown.visible = true;
		}
		
		protected function OnMouseUp(event:MouseEvent):void
		{
			if(mDown != null)
			{
				mDown.visible = false;
			}
			//this.dispatchEvent(event);
		}
		
		protected function OnMouseOver(event:MouseEvent):void
		{
			if( mSelected || !mEnabled)
				return ;
			
			if( this.contains( mUp ) )
				this.removeChild(mUp);
				
			this.addChild(mOver);
			this.setChildIndex(mDown, this.numChildren -1);
			
		}
		
		protected function OnMouseOut(event:MouseEvent):void
		{
			if( mSelected || !mEnabled)
				return ;
				
			if( this.contains( mOver ) )
				this.removeChild(mOver);
				
			this.addChild(mUp);
		}
		
		
		
		
	}
}